package com.soxing.braindata.common.config;

import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.Charset;
import java.util.List;

@Configuration
@ConfigurationProperties(prefix = "http", ignoreUnknownFields = true)
public class HttpClientConfig {
	/**
	 * 最大连接
	 */
	private Integer maxTotal;
	/**
	 * 每个host的最大连接
	 */
	private Integer defaultMaxPerRoute;
	/**
	 * 连接超时时间
	 */
	private Integer connectTimeout;
	/**
	 * 请求超时时间
	 */
	private Integer connectionRequestTimeout;
	/**
	 * 响应超时时间
	 */
	private Integer socketTimeout;

	/**
	 * HttpClient连接池
	 * 
	 * @return
	 */
	@Bean
	public HttpClientConnectionManager httpClientConnectionManager() {
		PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
		connectionManager.setMaxTotal(maxTotal);
		connectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute);
		return connectionManager;
	}

	/**
	 * 注册RequestConfig
	 * 
	 * @return
	 */
	@Bean
	public RequestConfig requestConfig() {
		return RequestConfig.custom().setConnectTimeout(connectTimeout)
				.setConnectionRequestTimeout(connectionRequestTimeout).setSocketTimeout(socketTimeout).build();
	}

	/**
	 * 注册HttpClient
	 * 
	 * @param manager
	 * @param config
	 * @return
	 */
	@Bean
	public HttpClient httpClient(HttpClientConnectionManager manager, RequestConfig config) {
		return HttpClientBuilder.create().setConnectionManager(manager).setDefaultRequestConfig(config).build();
	}

	/**
	 * 使用连接池管理连接
	 * 
	 * @param httpClient
	 * @return
	 */
	@Bean
	public ClientHttpRequestFactory requestFactory(HttpClient httpClient) {
		return new HttpComponentsClientHttpRequestFactory(httpClient);
	}

	/**
	 * 使用HttpClient来初始化一个RestTemplate
	 * 
	 * @param requestFactory
	 * @return
	 */
	@Bean
	public RestTemplate restTemplate(ClientHttpRequestFactory requestFactory) {
		RestTemplate template = new RestTemplate(requestFactory);

		List<HttpMessageConverter<?>> list = template.getMessageConverters();
		for (HttpMessageConverter<?> mc : list) {
			if (mc instanceof StringHttpMessageConverter) {
				((StringHttpMessageConverter) mc).setDefaultCharset(Charset.forName("UTF-8"));
			}
		}
		return template;
	}

	public Integer getMaxTotal() {
		return maxTotal;
	}

	public void setMaxTotal(Integer maxTotal) {
		this.maxTotal = maxTotal;
	}

	public Integer getDefaultMaxPerRoute() {
		return defaultMaxPerRoute;
	}

	public void setDefaultMaxPerRoute(Integer defaultMaxPerRoute) {
		this.defaultMaxPerRoute = defaultMaxPerRoute;
	}

	public Integer getConnectTimeout() {
		return connectTimeout;
	}

	public void setConnectTimeout(Integer connectTimeout) {
		this.connectTimeout = connectTimeout;
	}

	public Integer getConnectionRequestTimeout() {
		return connectionRequestTimeout;
	}

	public void setConnectionRequestTimeout(Integer connectionRequestTimeout) {
		this.connectionRequestTimeout = connectionRequestTimeout;
	}

	public Integer getSocketTimeout() {
		return socketTimeout;
	}

	public void setSocketTimeout(Integer socketTimeout) {
		this.socketTimeout = socketTimeout;
	}
}
